package com.pipi.sso.web.shiro;

import com.pipi.sso.core.enums.CommonStatusEnum;
import com.pipi.sso.core.model.UserBO;
import com.pipi.sso.core.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * All rights Reserved, Designed By www.maihaoche.com
 * <p>
 * 实现AuthorizingRealm接口用户用户认证
 *
 * @Package com.pipi.oo.web.shiro
 * @date: 2019/3/19 7:09 PM
 * @Copyright: 2017-2020 www.maihaoche.com Inc. All rights reserved.
 */
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    /**
     * <p> 授权 </p>
     *
     * @param principalCollection
     * @return AuthorizationInfo
     * @throws
     * @date 2019/3/19 11:41 PM
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //查询用户名称
        UserBO userBO = new UserBO();
        userBO.setUsername(name);
        UserBO user = userService.queryByUserName(name);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //添加角色
        simpleAuthorizationInfo.addRole(user.getRole().getRoleCode());
        return simpleAuthorizationInfo;
    }

    /**
     * <p> 用户认证 </p>
     *
     * @param authenticationToken
     * @return AuthenticationInfo
     * @throws
     * @date 2019/3/19 11:09 PM
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken
    authenticationToken) throws AuthenticationException {
        //加这一步的目的是在Post请求的时候会先进认证，然后在到请求
        if (authenticationToken.getPrincipal() == null) {
            log.error("用户名为空！");
            throw new AccountException("用户名不能为空！");
        }
        //获取用户信息
        String username = authenticationToken.getPrincipal().toString();
        UserBO user = userService.queryByUserName(username);
        if (Objects.isNull(user)) {
            log.error("用户名不存在! username: {}", username);
            throw new AccountException("用户名错误！");
        }
        if (!user.getPassword().equals(new String((char[]) authenticationToken.getCredentials()))) {
            log.error("密码错误! username: {}, password: {}", user.getUsername(), user.getPassword());
            throw new AccountException("密码错误！请重新输入!");
        }
        if (!Objects.equals(CommonStatusEnum.YES.getCode(), user.getStatus())) {
            log.error("账号被禁用!userId is {}, status is {}", user.getUserId(), user.getStatus());
            throw new AccountException("账号被禁用");
        }
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("user", user.getUsername());
        //这里验证authenticationToken和simpleAuthenticationInfo的信息
        return new SimpleAuthenticationInfo(username, user.getPassword(), "user");
    }
}